package edu.uestc.gene.model;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class Tool {

	/**
	 * 参数为hadamard matrix的阶数n.<br>
	 * n,n/12,n/20之一必须为2的幂，所以调整阶数到最小合适值
	 * 
	 * @param order
	 * @return
	 */
	public static int adjustOrder(int order) {
		if (order % 12 == 0) {
			if (isPowerOfTwo(order / 12)) {
				return order;
			}
		}
		if (order % 20 == 0) {
			if (isPowerOfTwo(order / 20)) {
				return order;
			}
		}
		if (isPowerOfTwo(order)) {
			return order;
		} else {
			if (order % 2 == 0)
				return adjustOrder(order + 2);
			else
				return adjustOrder(order + 1);
		}
	}

	/**
	 * 判断给定整数是否为2的幂次
	 * 
	 * @param number
	 * @return
	 */
	public static boolean isPowerOfTwo(int number) {
		return ((number & (number - 1)) == 0);
	}

	/**
	 * 判断给定字符串是否整数
	 * 
	 * @param s
	 * @return
	 */
	public static boolean isNumeric(double value) {
		String s = value + "";
		if ((s != null) && (s != ""))
			return s.matches("^[0-9]*$|[0-9]*.0$");
		else
			return false;
	}

	public static double log2(int n) {
		return Math.log(n) / Math.log(2);
	}

	public static double getAverage(int[] array) {
		double sum = 0, num = array.length;
		for (int i = 0; i < num; i++) {
			sum += array[i];
		}
		return (double) (sum / num);
	}

	// 獲取標準差
	public static double getStandardDevition(int[] array) {
		double sum = 0, num = array.length, average = getAverage(array);
		for (int i = 0; i < num; i++) {
			sum += Math.sqrt(((double) array[i] - average)
					* ((double) array[i] - average));
		}
		return (sum / (num - 1));
	}

	public static String formatTimeString(long millisecond) {
		StringBuffer sb = new StringBuffer();
		long second = 1000, minute = second * 60, hour = minute * 60;
		if (millisecond >= hour) {
			int hours = (int) (millisecond / hour);
			sb.append(hours + "小时");
			millisecond -= hours * hour;
		}
		if (millisecond > minute) {
			int minutes = (int) (millisecond / minute);
			sb.append(minutes + "分");
			millisecond -= minutes * minute;
		}
		if (millisecond > second) {
			int seconds = (int) (millisecond / second);
			sb.append(seconds + "秒");
			millisecond -= second * seconds;
		}
		if (millisecond >= 0) {
			sb.append(millisecond + "毫秒");
		}
		return sb.toString();
	}

	/**
	 * 希尔排序
	 * 
	 * @param array
	 * @return
	 */
	public static int[] shellSort(int[] array) {
		if (!validate(array)) {
			return array;
		}
		int size = array.length, h = 1, in, out, temp;
		while (h < size / 3) {
			h = h * 3 + 1;
		}
		while (h > 0) {
			for (out = h; out < size; out++) {
				temp = array[out];
				in = out;
				while (in > h - 1 && array[in - h] >= temp) {
					array[in] = array[in - h];
					in -= h;
				}
				array[in] = temp;
			}
			h = (h - 1) / 3;
		}
		return array;
	}

	private static boolean validate(int[] array) {
		if (array == null) {
			return false;
		}
		int size = array.length;
		if (size == 0 || size == 1) {
			return false;
		}
		return true;
	}

	public static double round(double f, int scale) {
		return new BigDecimal(f).setScale(scale, BigDecimal.ROUND_HALF_UP)
				.doubleValue();
	}

	public static double roundDivision(int a, int b, int scale) {
		return round(a * 1.0 / b * 1.0, scale);
	}

	public static String roundDivisionString(int a, int b, int scale) {
		return new BigDecimal(a * 1.0 / b * 1.0).setScale(scale, 2).toString();
	}

	public static void main(String args[]) {
		double[] p = { 0.4 };
		System.out.println(getIntersectionOfProbability(p));
	}

	public static double getIntersectionOfProbability(double[] probs) {
		BigDecimal result = new BigDecimal(1);
		for (int i = 0; i < probs.length; i++) {
			result = result.multiply(new BigDecimal(1).subtract(new BigDecimal(
					probs[i])));
		}
		return new BigDecimal(1).subtract(result)
				.setScale(Statistics.ROUND_SCALE, BigDecimal.ROUND_HALF_UP)
				.doubleValue();
	}

	/**
	 * 去掉字符串所有空白符
	 * 
	 * @param str
	 * @return
	 */
	public String trimAll(String str) {
		return str = str.replaceAll("\\s*", "");
	}

	public static String readFile(String fileName) {
		StringBuffer sb = new StringBuffer();
		File file = new File(fileName);
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(file));
			String tempString = null;
			while ((tempString = reader.readLine()) != null) {
				sb.append(tempString + "\n");
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
		return sb.toString();
	}

	/**
	 * 写入文件
	 * 
	 * @param content
	 *            需要写入文件的内容
	 * @param path
	 *            需要写入文件的路径
	 * @param append
	 *            追加或写入
	 */
	public static void writeText(String content, String path, boolean append) {
		File file = new File(path);
		BufferedWriter bufferedWriter = null;
		try {
			if (!file.exists()) {
				file.createNewFile();
			}
			bufferedWriter = new BufferedWriter(new FileWriter(file));
			if (append) {
				bufferedWriter.append(content);
			} else {
				bufferedWriter.write(content);
			}
			bufferedWriter.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bufferedWriter.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 以行为单位读取文件，常用于读面向行的格式化文件
	 */
	public static List<String> getAllInfoByLine(String fileName) {
		List<String> list = new ArrayList<String>();
		File file = new File(fileName);
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(file));
			String tempString = null;
			int line = 1;
			// 一次读入一行，直到读入null为文件结束
			while ((tempString = reader.readLine()) != null) {
				list.add(tempString);
				line = line + 1;
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
		return list;
	}

}
